#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
# @Time    : 2024/11/26 11:45
# @Author  : zmz
# @File    : sensitivity_analysis.py
# @function: 敏感性分析
# @Software: PyCharm

import PySimpleGUI as sg
import matplotlib
import numpy_financial as npf
matplotlib.use('TkAgg')  # 或者 'Qt5Agg'
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np

# 敏感性分析布局
layout = [
    [sg.Text("期初投资(x)", size=(9, 1)), sg.Input(key='-INVESTMENT-', default_text="1855153.60", size=(20, 1)),
     sg.Text("销售量", size=(9, 1)), sg.Input(key='-PRODUCTION-', default_text="3000", disabled=False, size=(20, 1))],
    [sg.Text("销售收入(y)", size=(9, 1)), sg.Input(key='-SALES_REVENUE-', default_text="773068.80", disabled=False, size=(20, 1)),
       sg.Text("单价", size=(9, 1)), sg.Input(key='-UNIT_PRICE-', default_text="210", disabled=False, size=(20, 1))],
    [sg.Text("经营成本(z)", size=(9, 1)), sg.Input(key='-OPERATING_COST-', default_text="366100.00", size=(20, 1)),
       sg.Text("变化率hight", size=(9, 1)), sg.Input(key='-CHANGE_RANGE_END-', default_text="0.4", size=(20, 1)) ],
    [sg.Text("残值", size=(9, 1)), sg.Input(key='-SALVAGE_VALUE-', default_text="80", size=(20, 1)),
       sg.Text("变化率low", size=(9, 1)), sg.Input(key='-CHANGE_RANGE_START-', default_text="-0.3", size=(20, 1))],
    [sg.Text("折现率", size=(9, 1)), sg.Input(key='-DISCOUNT_RATE-', default_text="0.12", size=(20, 1)),
        sg.Text("变化率step", size=(9, 1)), sg.Input(key='-CHANGE_STEP-', default_text="0.1", size=(20, 1))],
    [sg.Text("寿命", size=(9, 1)), sg.Input(key='-LIFE-', default_text="24", size=(20, 1)),
        sg.Checkbox("使用销售量和单价计算销售收入时勾选", key='-USE_PROD_PRICE-', default=False)],
    [sg.Button("计算敏感性分析")],
    [sg.Table(
        values=[],
        headings=['Change Rate', '  NPV(x)  ', '  NPV(y)  ', '  NPV(z)  '],
        auto_size_columns=True,
        key='-TABLE-',
        display_row_numbers=False,
        size=(50,15)
    ),
        sg.Canvas(key='-CANVAS-',size=(20,20))]

]


 # 敏感性分析-计算NPV
def calculate_npv(values,base_investment, production, unit_price, operating_cost, salvage_value, discount_rate, life,
                   change_x, change_y, change_z):
    investment = base_investment * (1 + change_x)
    if unit_price is not None and production is not None:
        sales_revenue = unit_price * production * (1 + change_y)
    else:
        sales_revenue = float(values['-SALES_REVENUE-']) * (1 + change_y)

    operating_cost_changed = operating_cost * (1 + change_z)

    cash_flows = []
    for year in range(life):
        cash_flows.append((sales_revenue - operating_cost_changed))
    cash_flows.append((sales_revenue - operating_cost_changed) + salvage_value)

    return npf.npv(discount_rate, [-investment] + cash_flows)

 # 敏感性分析-绘图
def draw_figure(canvas, figure):
    figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
    figure_canvas_agg.draw()
    figure_canvas_agg.get_tk_widget().config(width=400, height=380)
    figure_canvas_agg.get_tk_widget().pack(side='top',  fill='both', expand=1)
    return figure_canvas_agg


# 敏感性分析处理
def Sensitivity_nalysis_handle(window,values):
    try:
        base_investment = float(values['-INVESTMENT-'])
        production = int(values['-PRODUCTION-']) if values['-USE_PROD_PRICE-'] else None
        unit_price = float(values['-UNIT_PRICE-']) if values['-USE_PROD_PRICE-'] else None
        operating_cost = float(values['-OPERATING_COST-'])
        salvage_value = float(values['-SALVAGE_VALUE-'])
        discount_rate = float(values['-DISCOUNT_RATE-'])
        life = int(values['-LIFE-'])

        change_range_start = float(values['-CHANGE_RANGE_START-'])
        change_range_end = float(values['-CHANGE_RANGE_END-'])
        change_step = float(values['-CHANGE_STEP-'])

        changes = np.arange(change_range_start, change_range_end, change_step)
        changes = np.append(changes, 0)
        changes_percentage = [f"{int(change * 100)}%" for change in changes]
        npv_x = [
            calculate_npv(values,base_investment, production, unit_price, operating_cost, salvage_value, discount_rate, life,
                          x, 0, 0) for x in changes]
        npv_y = [
            calculate_npv(values,base_investment, production, unit_price, operating_cost, salvage_value, discount_rate, life,
                          0, y, 0) for y in changes]
        npv_z = [
            calculate_npv(values,base_investment, production, unit_price, operating_cost, salvage_value, discount_rate, life,
                          0, 0, z) for z in changes]
        table_data = []
        for i in range(len(changes)):
            if changes[i] != 0:
                table_data.append([changes_percentage[i], round(npv_x[i], 2), round(npv_y[i], 2), round(npv_z[i], 2)])
        window['-TABLE-'].update(values=table_data)

        fig, ax = plt.subplots()
        ax.plot(changes_percentage, npv_x, label='NPV(x)')
        ax.plot(changes_percentage, npv_y, label='NPV(y)')
        ax.plot(changes_percentage, npv_z, label='NPV(z)')
        ax.set_xlabel('Change Rate')
        ax.set_ylabel('NPV')
        ax.set_title('Sensitivity Analysis')
        ax.legend()
        ax.grid(True)

        canvas = window['-CANVAS-'].TKCanvas
        draw_figure(canvas, fig)
    except ValueError as e:
        sg.popup(f"输入错误：请确保输入的都是合法的数值。{e}")




